#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
@Author   : long.hai
@Contact  : 1982964634@qq.com
"""
import re
from playwright.async_api import Page
from playwright._impl._errors import Error
from _base.errors import WaitTimeoutError, DOMError


class ElementAction(object):

    @staticmethod
    async def ele(page: Page, element):
        page = page if not element else element
        return page

    @staticmethod
    async def locator(page: Page, element, args, **kwargs):
        page = await ElementAction.ele(page, element)
        element = page.locator(args, **kwargs)
        return element

    @staticmethod
    async def get_by_placeholder(page: Page, element, args, **kwargs):
        page = await ElementAction.ele(page, element)
        element = page.get_by_placeholder(args, **kwargs)
        return element

    @staticmethod
    async def get_by_text(page: Page, element, text, **kwargs):
        page = await ElementAction.ele(page, element)
        element = page.get_by_text(text, **kwargs)
        return element

    @staticmethod
    async def get_by_role(page: Page, element, args, **kwargs):
        page = await ElementAction.ele(page, element)
        element = page.get_by_role(args, **kwargs)
        return element

    @staticmethod
    async def filter(page: Page, element, args, **kwargs):
        page = await ElementAction.ele(page, element)
        res_locator = re.findall(r"re\.compile\(r\"(.*?)\"\'", str(kwargs))
        if res_locator:
            element = page.filter(has_text=re.compile(r"%s" % (res_locator[0],)))
        else:
            element = page.filter(args, **kwargs) if args else page.filter(**kwargs)
        return element

    @staticmethod
    async def first(page: Page, element, args, **kwargs):
        page = await ElementAction.ele(page, element)
        element = page.first
        return element

    @staticmethod
    async def parent(page: Page, element, args, **kwargs):
        page = await ElementAction.ele(page, element)
        times = int(args) if args else 1
        for _ in range(times):
            element = page.locator('..')
        return element

    @staticmethod
    async def nth(page: Page, element, args, **kwargs):
        page = await ElementAction.ele(page, element)
        element = page.nth(int(args))
        return element

    @staticmethod
    async def xpath(page: Page, element, selector, **kwargs):
        page = await ElementAction.ele(page, element)
        element = page.locator(selector, **kwargs)  # selector
        await ElementAction.wait_element(page, selector)
        # await ElementAction.check_xpath_format(element)
        return element

    @staticmethod
    async def class_name(page: Page, element, args, **kwargs):
        page = await ElementAction.ele(page, element)
        selector = f'.{args}'
        element = page.locator(selector)
        await ElementAction.wait_element(page, selector)
        return element

    @staticmethod
    async def id(page: Page, element, element_id, **kwargs):
        page = await ElementAction.ele(page, element)
        selector = f'#{element_id}'
        element = page.locator(selector)
        await ElementAction.wait_element(page, selector)
        return element

    @staticmethod
    async def name(page: Page, element, args, **kwargs):
        page = await ElementAction.ele(page, element)
        selector = f"[name='{args}']"
        element = await page.query_selector(selector)
        await ElementAction.wait_element(page, selector)
        return element

    @staticmethod
    async def query_selector(page: Page, element, args, **kwargs):
        page = await ElementAction.ele(page, element)
        element = await page.query_selector(args)
        return element

    @staticmethod
    async def query_selector_all(page: Page, element, args, **kwargs):
        page = await ElementAction.ele(page, element)
        lr = await args.split(",")
        element = await page.query_selector_all(f'.{lr[0]}')[int(lr[1]) - 1]
        return element

    @staticmethod
    async def check_xpath_format(element, timeout=5000):
        try:
            await element.is_visible(timeout=timeout)
        except Error as e:
            raise DOMError(str(e.message))

    @staticmethod
    async def wait_element(page: Page, selector):
        try:
            await page.wait_for_selector(selector, timeout=10000)
        except Error:
            raise WaitTimeoutError(f'定位元素失败，等待元素 {selector} 出现时间超过 {5000}ms')
        except Exception as e:
            print("wait_element", str(e))
            raise e
